package com.zhaozixiang.generator.controller;

import com.zhaozixiang.generator.domain.ColumnInfo;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class TableMetaDataReader {
    private final Connection connection;

    public TableMetaDataReader(String url, String username, String password) throws SQLException {
        this.connection = DriverManager.getConnection(url, username, password);
    }

    /**
     * 获取表的字段信息
     */
    public List<ColumnInfo> getTableColumns(String tableName) throws SQLException {
        List<ColumnInfo> columns = new ArrayList<>();
        DatabaseMetaData metaData = connection.getMetaData();

        try (ResultSet rs = metaData.getColumns(null, null, tableName, null)) {
            while (rs.next()) {
                ColumnInfo column = new ColumnInfo();
                // 设置原始字段名
                String columnName = rs.getString("COLUMN_NAME");
                column.setName(columnName);
                // 关键修复：自动生成驼峰式属性名
                column.setJavaName(toCamelCase(columnName));
                // 设置其他属性
                column.setType(rs.getString("TYPE_NAME"));
                column.setRemarks(rs.getString("REMARKS"));
                column.setJavaType(this.convertToJavaType(column.getType()));
                columns.add(column);
            }
        }
        return columns;
    }

    /**
     * 数据库类型 → Java 类型转换（Java 8 兼容写法）
     */
    private String convertToJavaType(String dbType) {
        if (dbType == null) {
            return "Object";
        }
        // 统一转为大写处理
        String upperDbType = dbType.toUpperCase();

        switch (upperDbType) {
            // 字符串类型
            case "CHAR":
            case "VARCHAR":
            case "TINYTEXT":
            case "TEXT":
            case "MEDIUMTEXT":
            case "LONGTEXT":
            case "ENUM":
            case "SET":
                return "String";

            // 整数类型
            case "TINYINT":
                return "Boolean";
            case "SMALLINT":
            case "YEAR":
                return "Integer";
            case "INT":
            case "INTEGER":
            case "MEDIUMINT":
                return "Integer";
            case "BIGINT":
                return "Long";

            // 浮点类型
            case "FLOAT":
                return "Float";
            case "DOUBLE":
            case "REAL":
                return "Double";
            case "DECIMAL":
            case "NUMERIC":
                return "java.math.BigDecimal";

            // 日期时间类型
            case "DATE":
                return "java.time.LocalDate";
            case "TIME":
                return "java.time.LocalTime";
            case "DATETIME":
            case "TIMESTAMP":
                return "java.time.LocalDateTime";

            // 二进制类型
            case "BIT":
                return "Boolean";
            case "BINARY":
            case "VARBINARY":
            case "TINYBLOB":
            case "BLOB":
            case "MEDIUMBLOB":
            case "LONGBLOB":
                return "byte[]";

            // JSON类型
            case "JSON":
                return "String"; // 或自定义JSON对象类型

            default:
                return "Object"; // 未知类型
        }
    }

    /**
     * 下划线命名转驼峰命名
     */
    private String toCamelCase(String columnName) {
        StringBuilder result = new StringBuilder();
        String[] parts = columnName.split("_");
        for (int i = 0; i < parts.length; i++) {
            if (i == 0) {
                result.append(parts[i].toLowerCase());
            } else {
                result.append(parts[i].substring(0, 1).toUpperCase())
                        .append(parts[i].substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    /**
     * 获取表的主键
     */
    public List<String> getPrimaryKeys(String tableName) throws SQLException {
        List<String> primaryKeys = new ArrayList<>();
        DatabaseMetaData metaData = connection.getMetaData();

        try (ResultSet rs = metaData.getPrimaryKeys(null, null, tableName)) {
            while (rs.next()) {
                primaryKeys.add(rs.getString("COLUMN_NAME"));
            }
        }
        return primaryKeys;
    }

    public void close() throws SQLException {
        if (connection != null) {
            connection.close();
        }
    }
}
